/**
 * Thinking in Java
 *
 * @version 4th
 * @author Bruce Eckel
 * @see http://www.MindView.net
 */

/**
 * This program demonstrates ensuring proper cleanup
 */

/**
 * basic-class
 */
class Shape {
    /**
     * constructor
     * @param i
     */
    Shape(int i) {
        System.out.println("Shape constructor");
    }

    /**
     * method dispose
     */
    void dispose() {
        System.out.println("Shape dispose");
    }
}

/**
 * class Circle
 */
class Circle extends Shape {
    Circle(int i) {
        super(i);
        System.out.println("Drawing Circle");
    }

    void dispose() {
        System.out.println("Erasing Circle");
        super.dispose();
    }
}

/**
 * class Triangle
 */
class Triangle extends Shape {
    Triangle(int i) {
        super(i);
        System.out.println("Drawing Triangle");
    }

    void dispose() {
        System.out.println("Erasing Triangle");
        super.dispose();
    }
}

/**
 * class Line
 */
class Line extends Shape {
    private int start, end;
    Line(int start, int end) {
        super(start);
        this.start = start;
        this.end = end;
        System.out.println("Drawing Line: " + start + ", " + end);
    }

    void dispose() {
        System.out.println("Erasing Line: " + start + ", " + end);
        super.dispose();
    }
}

/**
 * class CADSystem
 * 继承自Shape, 组合Circle, Triangle, Line
 */
public class CADSystem extends Shape {
    private Circle c;
    private Triangle t;
    private Line[] lines = new Line[3];

    public CADSystem(int i) {
        super(i + 1);
        for (int j = 0; j < lines.length; j++) {
            lines[j] = new Line(j, j*j);
        }
        c = new Circle(1);
        t = new Triangle(1);
        System.out.println("Combined constructor");
    }

    public void dispose() {
        System.out.println("CADSystem.dispose()");
        t.dispose();
        c.dispose();
        for (int i = lines.length - 1; i >= 0; i--) {
            lines[i].dispose();
        }
        super.dispose();
    }

    /**
     * main()
     * 
     * @param args array of string arguments
     */
    public static void main(String[] args) {
        CADSystem x = new CADSystem(47);
        try {

        } finally {
            x.dispose();
        }
    }
}

/** 
 * output:
 * Shape constructor
 * Shape constructor
 * Drawing Line: 0, 0
 * Shape constructor
 * Drawing Line: 1, 1
 * Shape constructor
 * Drawing Line: 2, 4
 * Shape constructor
 * Drawing Circle
 * Shape constructor
 * Drawing Triangle
 * Combined constructor
 * CADSystem.dispose()
 * Erasing Triangle
 * Shape dispose
 * Erasing Circle
 * Shape dispose
 * Erasing Line: 2, 4
 * Shape dispose
 * Erasing Line: 1, 1
 * Shape dispose
 * Erasing Line: 0, 0
 * Shape dispose
 * Shape dispose
 */
